
#include <stdint.h>
#include "Bsp.h"

#include "BooterFlag.h"
#include "BooterConfig.h"

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    1

/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - __NVIC_PRIO_BITS) )

#define portDISABLE_INTERRUPTS()							\
{															\
	__set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY );	\
	__DSB();												\
	__ISB();												\
}


typedef void (*Function_T)(void);


#define STACK_CHECK(addr)	(((addr) & 0x2FFE0000) == 0x20000000)

#define STACK_ADDR(app_addr)	(*(volatile uint32_t*)(app_addr))
#define JUMP_ADDR(app_addr)		(*(volatile uint32_t *)((app_addr)+4))
#define JUMP_TO_ADDR(addr)		((Function_T)(addr))();

void Booter_RunApp(void) {	
	if(STACK_CHECK(STACK_ADDR(APP_ADDRESS))){
		portDISABLE_INTERRUPTS();
		nvic_vector_table_set(NVIC_VECTTAB_FLASH, APP_ADDRESS - FLASH_BASE);
		__set_MSP(STACK_ADDR(APP_ADDRESS));
		JUMP_TO_ADDR(JUMP_ADDR(APP_ADDRESS)); 
	}
}

static uint32_t Booter_AppVerify(uint32_t AppStartAddress, uint32_t AppSize){
	return STACK_CHECK(STACK_ADDR(AppStartAddress));
}

uint32_t Booter_CheckApp(uint32_t AppStartAddress, uint32_t AppSize){
	return STACK_CHECK(STACK_ADDR(AppStartAddress));
}


